Rendering and displaying three dimensional (3-D) graphics on screen typically involves many calculations and computations. In a simple graphics system, such computations occur according to some level of cooperative or shared processing by the central processing unit (CPU) and the graphics processing unit (GPU). In an exemplary scenario, after instructions are processed and some initial computations occur in the CPU, a set of coordinate points or vertices that define the object to be rendered are stored in video memory for further processing by the GPU in the graphics pipeline. When graphics programmers develop graphics applications via a set of available graphics APIs, the programmer generally indicates a set of vertices to be operated upon by a set of algorithmic elements.
The data is sent into the graphics pipeline, and each vertex is streamed through a configurable set of GPU subunits. One or more programmable shader units, sometimes referred to as shaders or “shader programs,” can operate on the data and perform specialized operations on graphics data. Shaders can include, for example, vertex shader(s), geometry shader(s) and pixel shader(s).
Rather than creating a plurality of different shader programs for each specific scenario, a single shader program can receive different combinations of shader constants, and depending on the combination of particular shader constants that are selected, the output of the shader will vary. These shader constants can specify, for example, how pixels are combined, how data is read in and out, and in the case of a texture, how values are extracted from that texture. Shader constants can be used to specify, for example, things like light positions, view transformations which certain objects undergo, material parameters such as color and reflectivity. For instance, a particular shader program can be fed different constants which can define, for example, what type of surface is present and how in view of those constants the light would reflect off a particular surface. For example, light would reflect differently off a plain wood surface than it would off a laminated wood surface. The shader constants are used to specify how this reflection would occur. If the shader program is computing a lighting equation, the CPU can provide shader constants which define light positions or light colors. These constant values are unchanged throughout the shader invocation.
The process of shading is a computation intensive and complex process. When these specific shaders operate in a graphics pipeline, there are regular bottlenecks due to the operations that occur in each stage. One inefficiency in graphics programming results from time spent setting state and issuing commands to the GPU. “State” refers to a large amount of data (numbers or values) that describes how the hardware pipeline is to be configured, and how it will behave. One component of this state is a set of shader constants that need to be bound to the GPU before executing a shader program. It is desirable to reduce time spent setting state (e.g., shader constants) to the GPU.
Some shaders utilize constant buffers (as opposed to constant registers) which hold groups or aggregations of shader constants. Constant buffers can allow shader constants to be set to the GPU more rapidly since the aggregations of shader constants are grouped together.